iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
DevOps

菜逼八用Github Actions系列 第 22

Day 22 - concurrency & 提升效能

  • 分享至 

  • xImage
  •  

目錄

摘要

在上一篇我們學到如何使用fail-fast、continue-on-error

這篇我們會來會來了解一下什麼是並發性,以及如何幫workflow設並發性以提升執行效率

什麼是並發性

並發性是指同一時間處理多個任務的能力,但並不代表一定要同時進行,而是允許多個任務交替執行,以充分利用系統資源、提升系統的效率

https://ithelp.ithome.com.tw/upload/images/20240917/20135568HXgaVUdpSZ.png

Github Actions預設也允許一次執行多個workflow,但你也可以選擇一次只執行一個,這也是並發性

在workflow中設定並發性有以下好處

  1. 避免同時運行的workflow、job佔用太多資源,進而提高執行速度,並減低因為同時佔用過多而資源導致workflow不穩定或失敗
    但是有可能也會造成因為workflow、job被取消而漏執行workflow、job
  2. 避免版本覆蓋、錯亂 例如兩個開發者連續發不同版本的code到dev時,會觸發兩次deploy的workflow,如果又剛好第二次在第一次之前完成,就會導致版本覆蓋
  3. 減少花費
    例如某分支上了遠端,也發了PR,這時如果開發者馬上再改一個小東西,並推到遠端,同個PR就會有兩個unit test的workflow在跑,但其實前一次是不需要的,這就會導致資源浪費
    每個組織或者個人開發者根據plan的差異,有不同的免費執行workflow額度,不過只要超額就需要付費,且費用是以分鐘在計算的

使用concurrency

concurrency是一個控制workflow、job的並發性的屬性,我們可以透過在concurrency來幫workflow或job分組,一組中一次只有一個workflow或job被執行

當有設定concurrency的workflow被排入queue等待執行時,如果repo中有另一個屬於同個concurrency group的workflow或job又被排進去,則已排入queue狀態會變成pending,而pending的則被取消

同一個分支上的所有workflow,一次只執行一個

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

同一個分支上的同一個workflow,一次只執行一個

可用於跑unit test的workflow,因為多次連續推到遠端的情況,只要對最後一次執行workflow即可

on:
  push:
    branches:
      - main

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

同一個名稱以release/開頭的分支上的同一個workflow,一次只執行一個

非mono repo的情況下,可防止多個版本同時進行部署,以減少資源浪費、提高執行效率

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ contains(github.ref, 'release/')}}

其他設定job並發性的方法

使用job的needs

設定needs代表該job依賴於別的job,所以如果依賴的job還沒跑完前就不會執行,如果依賴的job失敗了也不會執行

jobs:
  build:
  deploy:
    needs: [build]
  send message to Slack channel:
    needs: [deploy]

使用workflow_run

當某名稱的workflow,達到某個執行階段時才執行

不過這個方法不能超過3層,如果硬要這麼做的話第4層開始就不會觸發 (A → B → C → D可以,超過D後就不行)

name: Send Slack notification

# 當名為Deploy的workflow完成時執行
on:
  workflow_run:
    workflows: [Deploy]
    types: [completed]

使用matrix和max-parallel

限制matrix job的最大平行執行數為1,如果為true則一個step失敗後,直接取消後面的所有job

不過沒有辦法控制哪個job先執行,所以這個方法適用於只要確保所有job成功執行,且job之間沒依賴性

jobs: 
  prepare-for-dessert:
    fail-fast: true
    strategy:
      max-parallel: 1    
      matrix:
        fruit: [mango, strawberry]
        dessert: [cake, 'ice cream']

上一篇
Day 21 - fail-fast策略 & continue-on-error策略
下一篇
Day 23 - 例子 - 把檔案上傳到Github Pages
系列文
菜逼八用Github Actions30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言